package com.eqs.enterprisequestionnaire.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eqs.enterprisequestionnaire.controller.AnswerController;
import com.eqs.enterprisequestionnaire.mapper.OptionMapper;
import com.eqs.enterprisequestionnaire.mapper.QuestionMapper;
import com.eqs.enterprisequestionnaire.mapper.QuestionnaireMapper;
import com.eqs.enterprisequestionnaire.model.pojo.Option;
import com.eqs.enterprisequestionnaire.model.pojo.Question;
import com.eqs.enterprisequestionnaire.model.pojo.Questionnaire;
import com.eqs.enterprisequestionnaire.model.pojo.Response;
import com.eqs.enterprisequestionnaire.service.HistoryService;
import com.eqs.enterprisequestionnaire.service.QuestionService;
import com.eqs.enterprisequestionnaire.service.QuestionnaireService;
import com.eqs.enterprisequestionnaire.service.ResponseService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class QuestionnaireImpl extends ServiceImpl<QuestionnaireMapper, Questionnaire> implements QuestionnaireService {
    @Autowired
    QuestionnaireMapper questionnaireMapper;
    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    OptionMapper optionMapper;
    @Autowired
    private ResponseService responseService;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private HistoryService historyService;
    public Questionnaire insertQuestionnaire(Integer authorId,String title,String description){
        QueryWrapper<Questionnaire> queryWrapper = new QueryWrapper<>();
        int count = Math.toIntExact(questionnaireMapper.selectCount(queryWrapper));
        boolean isEmpty = (count == 0);
        Questionnaire questionnaire=new Questionnaire();
        if(isEmpty){
            questionnaire.setId(1);
        }else{
            questionnaire.setId(selectMaxId()+1);
        }
        questionnaire.setAuthorId(authorId);
        questionnaire.setTitle(title);
        questionnaire.setDescription(description);
        questionnaire.setCreatedTime(LocalDateTime.now());
        questionnaire.setStatus(false);
        questionnaireMapper.insert(questionnaire);
        return questionnaire;
    }
    public Integer selectMaxId(){
        QueryWrapper<Questionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(id) as id");
        Questionnaire questionnaire = questionnaireMapper.selectOne(queryWrapper);
        return questionnaire != null ? questionnaire.getQuestionnaireId() : 0;
    }
    public Questionnaire selectByQuestionnaireId(Integer questionnaireId){
        return questionnaireMapper.selectById(questionnaireId);
    }
    public void updateQuestionnaire(@NotNull Questionnaire questionnaire){
        Questionnaire existingQuestionnaire = selectByQuestionnaireId(questionnaire.getQuestionnaireId());
        if (existingQuestionnaire != null) {
            // 使用 BeanUtils.copyProperties 进行属性赋值
            BeanUtils.copyProperties(questionnaire, existingQuestionnaire,getNullPropertyNames(questionnaire));
            existingQuestionnaire.setUpdatedTime(LocalDateTime.now());
            // 更新数据库中的用户信息
            questionnaireMapper.updateById(existingQuestionnaire);
        } else {
            throw new RuntimeException("Questionnaire not found");
        }
    }
    @NotNull
    private String[] getNullPropertyNames(Questionnaire source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
    public void deleteQuestionnaire(Integer questionnaireId){
        questionnaireMapper.deleteById(questionnaireId);

        QueryWrapper<Question> questionQueryWrapper = new QueryWrapper<>();
        questionQueryWrapper.eq("questionnaire_id", questionnaireId);
        List<Question> questions = questionMapper.selectList(questionQueryWrapper);

        for (Question question : questions) {
            // 删除与每个问题相关的所有选项
            QueryWrapper<Option> optionQueryWrapper = new QueryWrapper<>();
            optionQueryWrapper.eq("question_id", question.getQuestionId());
            optionMapper.delete(optionQueryWrapper);
            // 删除问题本身
            questionMapper.deleteById(question.getQuestionId());
        }
    }
    public void updateDeadline(Integer questionnaireId, LocalDateTime newDeadline){
        Questionnaire questionnaire = selectByQuestionnaireId(questionnaireId);
        if (questionnaire != null) {
            questionnaire.setDeadline(newDeadline);
            questionnaire.setUpdatedTime(LocalDateTime.now());
            questionnaireMapper.updateById(questionnaire);
        } else {
            throw new RuntimeException("Questionnaire not found");
        }
    }
    public void updateQuestionnaireStatus(Integer questionnaireId){
        Questionnaire questionnaire = selectByQuestionnaireId(questionnaireId);
        if (questionnaire != null) {
            boolean currentStatus = questionnaire.getStatus();
            questionnaire.setStatus(!currentStatus);
            questionnaire.setUpdatedTime(LocalDateTime.now());
            questionnaireMapper.updateById(questionnaire);
        } else {
            throw new RuntimeException("Questionnaire not found");
        }
    }
    public int getQuestionnaireResponseCount(Integer questionnaireId){
        QueryWrapper<Response> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("questionnaire_id", questionnaireId);
        return (int) responseService.count(queryWrapper);
    }
    public Questionnaire getQuestionnaireAfterCreat(Integer authorId, String title){
        QueryWrapper<Questionnaire> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("author_id",authorId).eq("title",title);
        return questionnaireMapper.selectOne(queryWrapper);
    }
    private Long getCountQuestionByAuthorAndeTitle(Integer authorId, String title){
        QueryWrapper<Questionnaire> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("author_id",authorId).eq("title",title);
        return questionnaireMapper.selectCount(queryWrapper);
    }
    public Questionnaire submitWholeQuestionnaire(Questionnaire questionnaire){
        // Create a counter for the title suffix
        int m = 1;
        String originalTitle = questionnaire.getTitle();
        // Check if a questionnaire with the same title already exists, and update the title if necessary
        while (getCountQuestionByAuthorAndeTitle(questionnaire.getAuthorId(),questionnaire.getTitle())>=1) {
            questionnaire.setTitle(originalTitle + "(" + m + ")");
            m++;
        }
        insertQuestionnaire(questionnaire.getAuthorId(),questionnaire.getTitle(),questionnaire.getDescription());//插入新问卷
        questionnaire.setId(getQuestionnaireAfterCreat(questionnaire.getAuthorId(),questionnaire.getTitle()).getId());//问卷id
        List<Question> questionList=questionnaire.getQuestions();
        List<Question> newQuestionList=new ArrayList<>();
        for (int i = 0; i < questionList.size(); i++) {
            Question q= questionList.get(i);
            q.setOrdination(i+1);
            q.setQuestionnaireId(questionnaire.getId());
            questionMapper.insert(q);//存储问题
            q.setId(questionService.getQuestionAfterCreat(q).getId());
            for (int j = 0; j < q.getOptions().size(); j++) {
                Option op=q.getOptions().get(j);
                op.setOrdination(j+1);
                op.setQuestionId(q.getId());
                optionMapper.insert(op);
            }
        }
        return historyService.getWholeQuestionnaire(questionnaire.getId());
    }

    //更新
    @Transactional
    public Questionnaire updateWholeQuestionnaire(Questionnaire questionnaire) {
        // Fetch the existing questionnaire from the database
        Questionnaire existingQuestionnaire = questionnaireMapper.selectById(questionnaire.getId());
        if (existingQuestionnaire == null) {
            throw new RuntimeException("Questionnaire with ID " + questionnaire.getId() + " does not exist.");
        }

        // Update the title and description of the questionnaire
        existingQuestionnaire.setTitle(questionnaire.getTitle());
        existingQuestionnaire.setDescription(questionnaire.getDescription());
        questionnaireMapper.updateById(existingQuestionnaire);

        // Delete existing questions and options associated with the questionnaire
        List<Question> existingQuestions = historyService.getListQuestionByQuestionnaireId(questionnaire.getId());
        for (Question existingQuestion : existingQuestions) {
            optionMapper.delete(new QueryWrapper<Option>().eq("question_id", existingQuestion.getId()));
            questionMapper.deleteById(existingQuestion.getId());
        }

        // Insert new questions and options
        List<Question> questionList = questionnaire.getQuestions();
        for (int i = 0; i < questionList.size(); i++) {
            Question q = questionList.get(i);
            q.setOrdination(i + 1);
            q.setQuestionnaireId(questionnaire.getId());
            questionMapper.insert(q); // Insert new question
            q.setId(questionService.getQuestionAfterCreat(q).getId()); // Get inserted question ID

            // Insert options for the question
            List<Option> optionList = q.getOptions();
            for (int j = 0; j < optionList.size(); j++) {
                Option op = optionList.get(j);
                op.setOrdination(j + 1);
                op.setQuestionId(q.getId());
                optionMapper.insert(op);
            }
        }

        return historyService.getWholeQuestionnaire(questionnaire.getId());
    }
    @Transactional
    public void deleteWholeQuestionnaire(Integer questionnaireId){
        // Delete existing questions and options associated with the questionnaire
        List<Question> existingQuestions = historyService.getListQuestionByQuestionnaireId(questionnaireId);
        for (Question existingQuestion : existingQuestions) {
            optionMapper.delete(new QueryWrapper<Option>().eq("question_id", existingQuestion.getId()));
            questionMapper.deleteById(existingQuestion.getId());
        }
        questionnaireMapper.deleteById(questionnaireId);
    }
}
